using System;
using System.Collections.Generic;
using System.Text;

namespace WOWEquipOptimizer.Shaman
{
    class Elemental : CasterDD
    {
        public Elemental()
            : base()
        {
            AllowShield = true;
            m_Base = new List<Attribute>();
            m_Base.Add(new Attribute(AttributeName.Mana, 2678));
            m_Base.Add(new Attribute(AttributeName.Health, 3000));
            m_Base.Add(new Attribute(AttributeName.Stamina, 116));
            m_Base.Add(new Attribute(AttributeName.Intellect, 103));
            m_Base.Add(new Attribute(AttributeName.Spirit, 122));
            m_Base.Add(new Attribute(AttributeName.CritSpellRating, 2.2f*CritSpellRating));
            // talents
            m_Base.Add(new Attribute(AttributeName.CritSpellRating, 11 * CritSpellRating));
            m_Base.Add(new Attribute(AttributeName.HitSpellRating, 9 * HitSpellRating));
            foreach (Attribute attr in m_Base)
            {
                handleAttribute(attr);
            }
            /*
             * Above is the proper way to do it, since this actually covers all the buffs properly
             */            
            Buff firewrath = new Buff("Totem of Wrath", new List<Attribute>());
            firewrath.Attributes.Add(new Attribute(AttributeName.CritSpellRating, 3 * CritSpellRating));
            firewrath.Attributes.Add(new Attribute(AttributeName.HitSpellRating, 3 * HitSpellRating));
            Buffs.Add(firewrath);
        }
        // // mana, int, spirit, spelldmg, spellcrit, spellhit, spellhaste,mp5
        public override float evaluateTF()
        {
            float runtime = 600;
            float time = runtime;
            float spellhit =(float) Math.Min(0.83f + m_Equip[AttributeName.HitSpellRating] / HitSpellRating, 0.99f);
            float spellcrit = m_Equip[AttributeName.CritSpellRating] / CritSpellRating;
            float spelldmg = m_Equip[AttributeName.SpellDamage];
            float spellhaste = 1 + m_Equip[AttributeName.HasteSpellRating] / 100f;
            float LB12Cast = Math.Max(2f / spellhaste, 1.5f);
            float LB12Dmg = ((563 + 643) / 2f) * 1.05f;
            float ManaRegIC = m_Equip[AttributeName.MP5] / 5f;
            if (this.SpecialValues.Contains("12327519"))
            {
                spellcrit += 35 / CritSpellRating;
                spelldmg += 45;
                ManaRegIC += 15 / 5;
            }
            float ManaRegOOC = ManaRegIC + (m_Equip[AttributeName.Spirit] / 5f + 15f) / 2;
            float LB12Mana = 330 * 0.9f * (1 - spellhit * 0.6f * (spellcrit / 100f)) - ManaRegIC * LB12Cast;
            if (this.SpecialValues.Contains("24066084"))
            {
                LB12Mana -= 24;
            }
            LB12Mana = Math.Max(LB12Mana, 1);
            float count = (float)Math.Floor(m_Equip[AttributeName.Mana] / LB12Mana);
            float castuseratio = (ManaRegOOC * LB12Cast) / LB12Mana;
            time -= count * LB12Cast + Math.Max(5 * castuseratio, 5);
            time = Math.Max(time, 0);
            float lbmult = 1.05f;
            if(this.SpecialValues.Contains("25991384"))
            {
                lbmult *= 1.05f;
            }
            if (this.SpecialValues.Contains("5491180"))
            {
                spelldmg += 85;
            }
            if(time > 0)
            {
                float regtime = time / (castuseratio + 1);
                time -= regtime;
            }
            count += (float)Math.Floor(time / LB12Cast);
            count = Math.Min(count, runtime / LB12Cast);
            float DMGLB12 = (1 + spellcrit / 100) * spellhit * lbmult * (LB12Dmg + (6 / 7f) * spelldmg) * count;
            return CondFactor * DMGLB12 / runtime;
        }
        // mana, int, spirit, spelldmg, spellcrit, spellhit, spellhaste, mp5,health
        public override void handleAttribute(Attribute attr)
        {
            switch (attr.Type)
            {
                case AttributeName.Intellect:
                    m_Equip[AttributeName.Mana] += attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) * 15;
                    m_Equip[AttributeName.Intellect] += attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f);
                    m_Equip[AttributeName.CritSpellRating] += (attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) / 80f) * CritSpellRating;
                    m_Equip[AttributeName.MP5] += (attr.Value * (HasBlessingOfKings ? 1.1f : 1.0f) / 10f);
                    break;
                case AttributeName.NatureSpellDamage:
                case AttributeName.SpellDamage:
                    m_Equip[AttributeName.SpellDamage] += attr.Value;
                    break;
                default:
                    base.handleAttribute(attr);
                    break;
            }
        }
        public override List<Item> filterEquip(List<Item> input)
        {
            input = base.filterEquip(input);
            List<Item> retval = new List<Item>();
            ItemBlacklist.Add("Atiesh, Greatstaff of the Guardian");
            ItemBlacklist.Add("Violet Signet");
            foreach (Item item in input)
            {
                if ((item.AllowableClasses & CharacterClass.Shaman) == 0) continue;
                if (item.GetType() == typeof(Weapon))
                {
                    Weapon weapon = (Weapon)item;
                    if (weapon.WeaponSlot == WeaponSlot.Ranged && weapon.Type != WeaponType.Totem) continue;
                    if (weapon.Type == WeaponType.Sword) continue;
                    if (weapon.TwoHand && weapon.Type != WeaponType.Staff) continue;
                }
                else if (item.GetType() == typeof(Armor))
                {
                    Armor armor = (Armor)item;
                    if ((armor.Type & (ArmorProficiency.Mail | ArmorProficiency.Shield)) == 0) continue;
                }
                if (SetBlacklist.Contains(item.Set.Name)) continue;
                if (ItemBlacklist.Contains(item.Name)) continue;
                retval.Add(item);
            }
            return handleWhiteList(retval);
        }
        public override bool evaluateBuild(int[] build)
        {
            if (build[0] >= 41 && build[2] >= 13)
            {
                return true;
            }
            else return false;
        }
    }
}
